package xcache

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

// 设置缓存信息，参照默认时间
//
//	key		缓存key
//	value	缓存值
func Set[T string | CacheKey](key T, value any) error {
	return SetExt(key, value, defaultExpr)
}

// 设置缓存信息，并设置过期时间
//
//	key		缓存key
//	value	缓存值
//	ext		过期时间
func SetExt[T string | CacheKey](key T, value any, ext time.Duration) error {
	byt := ""
	switch bs := value.(type) {
	case string:
		byt = bs
	case int, uint, int64, uint64, int8, uint8, int16, uint16, int32, uint32:
		byt = fmt.Sprintf("%d", bs)
	case float32, float64:
		byt = fmt.Sprintf("%f", bs)
	default:
		b, _ := json.Marshal(value)
		byt = string(b)
	}
	dat := cacheData{
		Value:  byt,
		Expire: time.Now().Add(ext).Unix(),
	}
	k := string(key)
	if !strings.Contains(k, ":") {
		k = defaultGroup + ":" + k
	}
	cacheSync.Store(k, dat)
	// 分级存储
	b, _ := json.Marshal(dat)
	for i := 0; i < len(cacheLevel); i++ {
		err := cacheLevel[i].Store(k, string(b), ext)
		if err != nil {
			// 为近最大可能使用缓存，设置失败后不清除该缓存key
			return fmt.Errorf("cache level %d[%s] store error:%w", i, cacheLevel[i].Name(), err)
		}
	}
	return nil
}
